package com.luo.backend.service;

import com.luo.backend.dto.*;
import com.luo.backend.entity.*;
import com.luo.backend.repository.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 评价服务类
 */
@Service
public class ReviewService {
    
    private static final Logger logger = LoggerFactory.getLogger(ReviewService.class);
    private static final Integer STATUS_NORMAL = 1;    // 正常状态
    private static final Integer STATUS_DELETED = 0;   // 已删除状态
    
    @Autowired
    private ReviewRepository reviewRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private MerchantRepository merchantRepository;
    
    @Autowired
    private FoodRepository foodRepository;
    
    /**
     * 创建评价
     */
    @Transactional
    public ReviewResponse createReview(Long userId, ReviewRequest request) {
        logger.info("用户 {} 创建评价，订单ID: {}", userId, request.getOrderId());
        
        // 1. 验证订单是否存在
        Order order = orderRepository.findById(request.getOrderId())
                .orElseThrow(() -> new RuntimeException("订单不存在"));
        
        // 2. 验证订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权评价该订单");
        }
        
        // 3. 验证订单状态（只有已完成的订单才能评价）
        if (!"delivered".equals(order.getStatus())) {
            throw new RuntimeException("只有已完成的订单才能评价");
        }
        
        // 4. 验证订单是否已评价
        if (reviewRepository.existsByOrderId(request.getOrderId())) {
            throw new RuntimeException("该订单已评价");
        }
        
        // 5. 验证评分范围（1-5）
        if (request.getOverallRating() == null || request.getOverallRating() < 1 || request.getOverallRating() > 5) {
            throw new RuntimeException("评分必须在1-5之间");
        }
        
        // 6. 验证可选评分范围
        if (request.getTasteRating() != null && (request.getTasteRating() < 1 || request.getTasteRating() > 5)) {
            throw new RuntimeException("口味评分必须在1-5之间");
        }
        if (request.getSpeedRating() != null && (request.getSpeedRating() < 1 || request.getSpeedRating() > 5)) {
            throw new RuntimeException("速度评分必须在1-5之间");
        }
        if (request.getPackageRating() != null && (request.getPackageRating() < 1 || request.getPackageRating() > 5)) {
            throw new RuntimeException("包装评分必须在1-5之间");
        }
        
        // 7. 验证内容长度（最多500字）
        if (request.getContent() != null && request.getContent().length() > 500) {
            throw new RuntimeException("评价内容最多500字");
        }
        
        // 8. 验证图片数量（最多9张）
        if (request.getImages() != null && request.getImages().size() > 9) {
            throw new RuntimeException("图片最多9张");
        }
        
        // 9. 创建评价
        Review review = new Review();
        review.setOrderId(request.getOrderId());
        review.setUserId(userId);
        review.setMerchantId(order.getMerchantId());
        review.setOverallRating(request.getOverallRating());
        review.setTasteRating(request.getTasteRating());
        review.setSpeedRating(request.getSpeedRating());
        review.setPackageRating(request.getPackageRating());
        review.setContent(request.getContent());
        review.setImages(request.getImages());
        review.setTags(request.getTags());
        review.setIsAnonymous(request.getIsAnonymous() != null ? request.getIsAnonymous() : false);
        review.setStatus(STATUS_NORMAL);
        
        Review savedReview = reviewRepository.save(review);
        
        // 10. 更新订单的 is_reviewed 字段
        order.setReviewed(true);
        orderRepository.save(order);
        
        // 11. 异步更新商家和商品的评分统计
        updateMerchantRatingStatistics(order.getMerchantId());
        if (savedReview.getFoodId() != null) {
            updateFoodRatingStatistics(savedReview.getFoodId());
        }
        
        logger.info("评价创建成功，评价ID: {}，已更新商家和商品评分统计", savedReview.getId());
        
        // 12. 构建响应
        ReviewResponse response = new ReviewResponse(savedReview);
        
        // 填充用户信息
        userRepository.findById(userId).ifPresent(user -> {
            response.setUsername(user.getUsername());
            response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
            response.setUserAvatar(user.getAvatar());   // ✅ 修复：设置头像URL
        });
        
        // 填充商家信息
        merchantRepository.findById(order.getMerchantId()).ifPresent(merchant -> {
            response.setMerchantName(merchant.getName());
        });
        
        return response;
    }
    
    /**
     * 获取订单的评价
     */
    public ReviewResponse getOrderReview(Long orderId) {
        logger.info("查询订单 {} 的评价", orderId);
        
        Review review = reviewRepository.findByOrderIdAndStatus(orderId, STATUS_NORMAL)
                .orElse(null);
        
        if (review == null) {
            return null;
        }
        
        ReviewResponse response = new ReviewResponse(review);
        
        // 填充用户信息（如果是匿名评价，返回"匿名用户"）
        if (review.getIsAnonymous()) {
            response.setUsername("匿名用户");
            response.setRealName("匿名用户");
            response.setUserAvatar(null);
        } else {
            userRepository.findById(review.getUserId()).ifPresent(user -> {
                response.setUsername(user.getUsername());
                response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
                response.setUserAvatar(user.getAvatar());   // ✅ 修复：设置头像URL
            });
        }
        
        // 填充商家信息
        merchantRepository.findById(review.getMerchantId()).ifPresent(merchant -> {
            response.setMerchantName(merchant.getName());
        });
        
        // 填充订单信息
        orderRepository.findById(orderId).ifPresent(order -> {
            response.setOrderNo(order.getOrderNo());
        });
        
        return response;
    }
    
    /**
     * 获取用户的评价列表
     */
    public ReviewListResponse getUserReviews(Long userId, Integer page, Integer size) {
        logger.info("获取用户 {} 的评价列表，页码: {}, 每页数量: {}", userId, page, size);
        
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Review> reviewPage = reviewRepository.findByUserIdAndStatusOrderByCreatedAtDesc(userId, STATUS_NORMAL, pageable);
        
        List<ReviewResponse> items = reviewPage.getContent().stream()
                .map(review -> {
                    ReviewResponse response = new ReviewResponse(review);
                    
                    // 填充商家信息
                    merchantRepository.findById(review.getMerchantId()).ifPresent(merchant -> {
                        response.setMerchantName(merchant.getName());
                        response.setMerchantLogo(merchant.getLogo());
                    });
                    
                    // 填充用户信息
                    userRepository.findById(review.getUserId()).ifPresent(user -> {
                        response.setUsername(user.getUsername());
                        response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
                        response.setUserAvatar(user.getAvatar());   // ✅ 修复：设置头像URL
                    });
                    
                    // 填充订单信息
                    orderRepository.findById(review.getOrderId()).ifPresent(order -> {
                        response.setOrderNo(order.getOrderNo());
                    });
                    
                    return response;
                })
                .collect(Collectors.toList());
        
        return new ReviewListResponse(items, reviewPage.getTotalElements());
    }
    
    /**
     * 删除评价（24小时内）
     */
    @Transactional
    public void deleteReview(Long userId, Long reviewId) {
        logger.info("用户 {} 删除评价 {}", userId, reviewId);
        
        // 1. 验证评价是否存在
        Review review = reviewRepository.findById(reviewId)
                .orElseThrow(() -> new RuntimeException("评价不存在"));
        
        // 2. 验证评价是否属于当前用户
        if (!review.getUserId().equals(userId)) {
            throw new RuntimeException("无权删除该评价");
        }
        
        // 3. 检查是否在24小时内
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime createdAt = review.getCreatedAt();
        if (createdAt.plusHours(24).isBefore(now)) {
            throw new RuntimeException("评价发布已超过24小时，不能删除");
        }
        
        // 4. 软删除（设置status = 0）
        review.setStatus(STATUS_DELETED);
        reviewRepository.save(review);
        
        // 5. 更新订单的 is_reviewed 字段
        orderRepository.findById(review.getOrderId()).ifPresent(order -> {
            order.setReviewed(false);
            orderRepository.save(order);
        });
        
        // 6. 更新商家和商品的评分统计
        updateMerchantRatingStatistics(review.getMerchantId());
        if (review.getFoodId() != null) {
            updateFoodRatingStatistics(review.getFoodId());
        }
        
        logger.info("评价删除成功，评价ID: {}，已更新商家和商品评分统计", reviewId);
    }
    
    /**
     * 获取商家评价公开列表（前端用户查看）
     */
    public MerchantReviewPublicListResponse getMerchantPublicReviews(Long merchantId, Integer page, Integer size,
                                                                      Integer rating, Boolean hasImage) {
        logger.info("获取商家 {} 的公开评价列表，页码: {}, 每页数量: {}, 评分: {}, 是否有图: {}",
                merchantId, page, size, rating, hasImage);
        
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Review> reviewPage;
        
        // 根据筛选条件查询（只查询正常状态的）
        if (rating != null && hasImage != null) {
            reviewPage = reviewRepository.findByMerchantIdAndRatingAndHasImage(merchantId, rating, hasImage, STATUS_NORMAL, pageable);
        } else if (rating != null) {
            reviewPage = reviewRepository.findByMerchantIdAndOverallRatingAndStatusOrderByCreatedAtDesc(merchantId, rating, STATUS_NORMAL, pageable);
        } else if (hasImage != null) {
            reviewPage = reviewRepository.findByMerchantIdAndHasImage(merchantId, hasImage, STATUS_NORMAL, pageable);
        } else {
            reviewPage = reviewRepository.findByMerchantIdAndStatusOrderByCreatedAtDesc(merchantId, STATUS_NORMAL, pageable);
        }
        
        List<ReviewResponse> items = reviewPage.getContent().stream()
                .map(review -> {
                    ReviewResponse response = new ReviewResponse(review);
                    
                    // 填充用户信息（如果是匿名评价，返回"匿名用户"）
                    if (review.getIsAnonymous()) {
                        response.setUsername("匿名用户");
                        response.setRealName("匿名用户");
                        response.setUserAvatar(null);
                    } else {
                        userRepository.findById(review.getUserId()).ifPresent(user -> {
                            response.setUsername(user.getUsername());
                            response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
                            response.setUserAvatar(user.getAvatar());   // ✅ 修复：设置头像URL
                        });
                    }
                    
                    // 填充订单信息
                    orderRepository.findById(review.getOrderId()).ifPresent(order -> {
                        response.setOrderNo(order.getOrderNo());
                    });
                    
                    return response;
                })
                .collect(Collectors.toList());
        
        // 获取评价统计
        MerchantReviewPublicListResponse.ReviewStatistics statistics = new MerchantReviewPublicListResponse.ReviewStatistics();
        
        // 总评价数
        long totalReviews = reviewRepository.countByMerchantIdAndStatus(merchantId, STATUS_NORMAL);
        statistics.setTotalReviews(totalReviews);
        
        // 平均评分
        Double averageRating = reviewRepository.getAverageRatingByMerchantId(merchantId, STATUS_NORMAL);
        if (averageRating == null) {
            averageRating = 0.0;
        }
        // 四舍五入到2位小数
        averageRating = Math.round(averageRating * 100.0) / 100.0;
        statistics.setAverageRating(averageRating);
        
        // 评分分布
        List<Object[]> distribution = reviewRepository.getRatingDistributionByMerchantId(merchantId, STATUS_NORMAL);
        Map<String, Long> ratingDistribution = new HashMap<>();
        
        // 初始化所有评分为0
        for (int i = 1; i <= 5; i++) {
            ratingDistribution.put(String.valueOf(i), 0L);
        }
        
        // 填充实际数据
        for (Object[] row : distribution) {
            Integer ratingValue = (Integer) row[0];
            Long count = (Long) row[1];
            ratingDistribution.put(String.valueOf(ratingValue), count);
        }
        statistics.setRatingDistribution(ratingDistribution);
        
        // 构建响应
        MerchantReviewPublicListResponse response = new MerchantReviewPublicListResponse();
        response.setItems(items);
        response.setTotal(reviewPage.getTotalElements());
        response.setPage(page);
        response.setPageSize(size);
        response.setStatistics(statistics);
        
        return response;
    }
    
    /**
     * 获取商家的评价列表（商家端）
     */
    public MerchantReviewListResponse getMerchantReviews(Long merchantId, Integer page, Integer size, 
                                                          Integer rating, Boolean hasReply, Boolean hasImage) {
        logger.info("获取商家 {} 的评价列表，页码: {}, 每页数量: {}, 评分: {}, 是否有回复: {}, 是否有图片: {}", 
                    merchantId, page, size, rating, hasReply, hasImage);
        
        Pageable pageable = PageRequest.of(page - 1, size);
        Page<Review> reviewPage;
        
        // 根据筛选条件查询（只查询正常状态的）
        if (rating != null && hasReply != null && hasImage != null) {
            // 三个条件都有
            reviewPage = reviewRepository.findByMerchantIdAndRatingAndHasReplyAndHasImage(
                merchantId, rating, hasReply, hasImage, STATUS_NORMAL, pageable);
        } else if (rating != null && hasReply != null) {
            // rating + hasReply
            reviewPage = reviewRepository.findByMerchantIdAndRatingAndHasReply(
                merchantId, rating, hasReply, STATUS_NORMAL, pageable);
        } else if (rating != null && hasImage != null) {
            // rating + hasImage
            reviewPage = reviewRepository.findByMerchantIdAndRatingAndHasImage(
                merchantId, rating, hasImage, STATUS_NORMAL, pageable);
        } else if (hasReply != null && hasImage != null) {
            // hasReply + hasImage
            reviewPage = reviewRepository.findByMerchantIdAndHasReplyAndHasImage(
                merchantId, hasReply, hasImage, STATUS_NORMAL, pageable);
        } else if (rating != null) {
            // 只有 rating
            reviewPage = reviewRepository.findByMerchantIdAndOverallRatingAndStatusOrderByCreatedAtDesc(
                merchantId, rating, STATUS_NORMAL, pageable);
        } else if (hasReply != null) {
            // 只有 hasReply
            reviewPage = reviewRepository.findByMerchantIdAndHasReply(
                merchantId, hasReply, STATUS_NORMAL, pageable);
        } else if (hasImage != null) {
            // 只有 hasImage
            reviewPage = reviewRepository.findByMerchantIdAndHasImage(
                merchantId, hasImage, STATUS_NORMAL, pageable);
        } else {
            // 没有筛选条件
            reviewPage = reviewRepository.findByMerchantIdAndStatusOrderByCreatedAtDesc(
                merchantId, STATUS_NORMAL, pageable);
        }
        
        List<ReviewResponse> items = reviewPage.getContent().stream()
                .map(review -> {
                    ReviewResponse response = new ReviewResponse(review);
                    
                    // 填充用户信息（处理匿名评价）
                    if (review.getIsAnonymous()) {
                        response.setUsername("匿名用户");
                        response.setRealName("匿名用户");
                        response.setUserAvatar(null);
                    } else {
                        userRepository.findById(review.getUserId()).ifPresent(user -> {
                            response.setUsername(user.getUsername());
                            response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
                            response.setUserAvatar(user.getAvatar());
                        });
                    }
                    
                    // 填充订单信息
                    orderRepository.findById(review.getOrderId()).ifPresent(order -> {
                        response.setOrderNo(order.getOrderNo());
                    });
                    
                    return response;
                })
                .collect(Collectors.toList());
        
        // 获取待回复数量
        long pendingReplyCount = reviewRepository.countPendingRepliesByMerchantId(merchantId, STATUS_NORMAL);
        
        return new MerchantReviewListResponse(items, reviewPage.getTotalElements(), pendingReplyCount);
    }
    
    /**
     * 商家回复评价
     */
    @Transactional
    public ReviewResponse replyReview(Long merchantId, Long reviewId, String reply) {
        logger.info("商家 {} 回复评价 {}", merchantId, reviewId);
        
        // 1. 验证评价是否存在
        Review review = reviewRepository.findById(reviewId)
                .orElseThrow(() -> new RuntimeException("评价不存在"));
        
        // 2. 验证评价是否属于当前商家
        if (!review.getMerchantId().equals(merchantId)) {
            throw new RuntimeException("无权回复该评价");
        }
        
        // 3. 验证是否已回复
        if (review.getMerchantReply() != null) {
            throw new RuntimeException("该评价已回复，不能重复回复");
        }
        
        // 4. 验证回复内容不能为空
        if (reply == null || reply.trim().isEmpty()) {
            throw new RuntimeException("回复内容不能为空");
        }
        
        // 5. 更新评价
        review.setMerchantReply(reply);
        review.setMerchantReplyAt(LocalDateTime.now());
        
        Review savedReview = reviewRepository.save(review);
        
        logger.info("评价回复成功，评价ID: {}", reviewId);
        
        // 6. 构建响应
        ReviewResponse response = new ReviewResponse(savedReview);
        
        // 填充用户信息
        userRepository.findById(review.getUserId()).ifPresent(user -> {
            response.setUsername(user.getUsername());
            response.setRealName(user.getRealName());  // ✅ 新增：设置真实姓名
            response.setUserAvatar(user.getAvatar());   // ✅ 修复：设置头像URL
        });
        
        // 填充商家信息
        merchantRepository.findById(review.getMerchantId()).ifPresent(merchant -> {
            response.setMerchantName(merchant.getName());
        });
        
        return response;
    }
    
    /**
     * 获取商家的评价统计
     */
    public ReviewStatisticsResponse getMerchantReviewStatistics(Long merchantId) {
        logger.info("获取商家 {} 的评价统计", merchantId);
        
        // 1. 总评价数
        long totalReviews = reviewRepository.countByMerchantIdAndStatus(merchantId, STATUS_NORMAL);
        
        // 2. 平均评分
        Double averageRating = reviewRepository.getAverageRatingByMerchantId(merchantId, STATUS_NORMAL);
        if (averageRating == null) {
            averageRating = 0.0;
        }
        // 四舍五入到2位小数
        averageRating = Math.round(averageRating * 100.0) / 100.0;
        
        // 3. 评分分布
        List<Object[]> distribution = reviewRepository.getRatingDistributionByMerchantId(merchantId, STATUS_NORMAL);
        Map<Integer, Long> ratingDistribution = new HashMap<>();
        
        // 初始化所有评分为0
        for (int i = 1; i <= 5; i++) {
            ratingDistribution.put(i, 0L);
        }
        
        // 填充实际数据
        for (Object[] row : distribution) {
            Integer rating = (Integer) row[0];
            Long count = (Long) row[1];
            ratingDistribution.put(rating, count);
        }
        
        // 4. 待回复数量
        long pendingReplyCount = reviewRepository.countPendingRepliesByMerchantId(merchantId, STATUS_NORMAL);
        
        return new ReviewStatisticsResponse(totalReviews, averageRating, ratingDistribution, pendingReplyCount);
    }
    
    /**
     * 检查订单是否可以评价
     */
    public boolean canReviewOrder(Long userId, Long orderId) {
        // 1. 订单是否存在
        Optional<Order> orderOpt = orderRepository.findById(orderId);
        if (!orderOpt.isPresent()) {
            return false;
        }
        
        Order order = orderOpt.get();
        
        // 2. 订单是否属于当前用户
        if (!order.getUserId().equals(userId)) {
            return false;
        }
        
        // 3. 订单状态是否为已完成
        if (!"delivered".equals(order.getStatus())) {
            return false;
        }
        
        // 4. 订单是否已评价
        if (reviewRepository.existsByOrderId(orderId)) {
            return false;
        }
        
        return true;
    }
    
    // ========== 私有方法：统计更新 ==========
    
    /**
     * 更新商家评分统计
     */
    @Transactional
    private void updateMerchantRatingStatistics(Long merchantId) {
        logger.info("更新商家 {} 的评分统计", merchantId);
        
        // 获取商家所有有效评价
        List<Review> reviews = reviewRepository.findByMerchantIdAndStatus(merchantId, STATUS_NORMAL);
        
        BigDecimal averageRating;
        Integer ratingCount;
        
        // 如果没有评价，恢复默认值
        if (reviews.isEmpty()) {
            averageRating = new BigDecimal("5.00");
            ratingCount = 0;
            logger.info("商家 {} 暂无评价，使用默认值", merchantId);
        } else {
            // ✅ 使用 BigDecimal 计算平均评分
            BigDecimal totalRating = reviews.stream()
                .map(Review::getOverallRating)           // Integer
                .map(BigDecimal::valueOf)                 // Integer → BigDecimal
                .reduce(BigDecimal.ZERO, BigDecimal::add); // 累加
            
            // 保留2位小数，四舍五入
            averageRating = totalRating.divide(
                BigDecimal.valueOf(reviews.size()), 
                2,                          // 保留2位小数
                RoundingMode.HALF_UP       // 四舍五入
            );
            
            ratingCount = reviews.size();
        }
        
        // 更新数据库
        merchantRepository.updateRatingStatistics(merchantId, averageRating, ratingCount);
        
        logger.info("✅ 商家 {} 的评分统计更新完成：平均评分 {}, 评价数量 {}", merchantId, averageRating, ratingCount);
    }
    
    /**
     * 更新商品评分统计
     */
    @Transactional
    private void updateFoodRatingStatistics(Long foodId) {
        if (foodId == null) {
            logger.info("商品ID为空，跳过商品评分统计更新");
            return;
        }
        
        logger.info("更新商品 {} 的评分统计", foodId);
        
        // 计算平均评分（只统计正常状态的评价）
        Double averageRatingDouble = reviewRepository.getAverageRatingByFoodId(foodId, STATUS_NORMAL);
        
        // 计算评价数量
        Long ratingCountLong = reviewRepository.countByFoodIdAndStatus(foodId, STATUS_NORMAL);
        
        BigDecimal averageRating;
        Integer ratingCount;
        
        // 如果没有评价，恢复默认值
        if (ratingCountLong == null || ratingCountLong == 0 || averageRatingDouble == null) {
            averageRating = new BigDecimal("5.00");
            ratingCount = 0;
            logger.info("商品 {} 暂无评价，使用默认值", foodId);
        } else {
            // ✅ 将 Double 转换为 BigDecimal 并保留2位小数
            averageRating = BigDecimal.valueOf(averageRatingDouble)
                .setScale(2, RoundingMode.HALF_UP);
            ratingCount = ratingCountLong.intValue();
        }
        
        // 更新数据库
        foodRepository.updateRatingStatistics(foodId, averageRating, ratingCount);
        
        logger.info("✅ 商品 {} 的评分统计更新完成：平均评分 {}, 评价数量 {}", foodId, averageRating, ratingCount);
    }
}
